#include "EventManager.h"


namespace re
{
	namespace core
	{
		IEventManager* IEventManager::this_ = NULL;

		void EventManager::VTriggerEvent(EventDataPtr data)
		{
			EventType type = data->VGetEventTypeId();
			EventTypeMap::iterator i = event_types_.find(type);
			if(i == event_types_.end())
			{
				assert(0 && "Attempt to trigger an event with unregistered id!");
				return;
			}
			//Inform all globals;
			EventListenerList::iterator list_iterator = global_listeners_.begin();
			EventListenerList::iterator list_iterator_end = global_listeners_.end();
			while(list_iterator != list_iterator_end)
			{
				list_iterator->get()->VHandleEvent(data);
				++list_iterator;
			}
			//Inform private listeners;
			list_iterator = i->second.begin();
			list_iterator_end = i->second.end();
			while(list_iterator != list_iterator_end)
			{
				list_iterator->get()->VHandleEvent(data);
				++list_iterator;
			}
		}
		void EventManager::VQueueEvent(EventDataPtr data)
		{
			queue_.push(data);
		}

		void EventManager::VTick()
		{
			//TODO: RIGHT AFTER THERE IS WORKING TIMER, MAKE THIS LOOP LIMITED TO 20ms, SO THE PROGRAM DON"T CRASH IF OTHER PROCESSES SPAM THE QUEUE
			EventDataPtr working_ptr;
			while(queue_.try_pop(working_ptr))
			{
				VTriggerEvent(working_ptr);
			}
		}

		void EventManager::VRegisterEvent(EventType type)
		{
			EventTypeMap::iterator i = event_types_.find(type);
			if(i != event_types_.end())
			{
				assert(0 && "Attempt to insert the same event twice!");
				return;
			}
			event_types_.insert(std::make_pair(type, EventListenerList()));
		}

		void EventManager::VRegisterListener(EventListenerPtr listener)
		{
			{
				EventListenerList::iterator i = global_listeners_.begin();
				EventListenerList::iterator end = global_listeners_.end();
				while(i != end)
				{
					if( *i == listener )
					{
						assert(0 && "Attempt to add the same listener twice!");
						return;
					}
					++i;
				}
			}
			{
				EventTypeMap::iterator i = event_types_.begin();
				EventTypeMap::iterator end = event_types_.end();
				while(i != end)
				{
					EventListenerList::iterator l = (*i).second.begin();
					EventListenerList::iterator l_end = (*i).second.end();
					while(l != l_end)
					{
						if((*l) == listener)
						{
							assert(0 && "Attempt to add a global listener, which is already added to a certain event.");
							return;
						}
						++l;
					}
					++i;
				}
			}
			global_listeners_.push_back(listener);
		}
		void EventManager::VRegisterListener(EventListenerPtr listener, EventType type)
		{
			EventTypeMap::iterator event_type = event_types_.find(type);
			if(event_type == event_types_.end())
			{
				assert(0 && "Attempt to add a listener to event type that doesn't exist!");
				return;
			}
			EventListenerList::iterator i = event_type->second.begin();
			EventListenerList::iterator end = event_type->second.end();
			while(i != end)
			{
				if(*i == listener)
				{
					assert(0 && "Attempt to add a listener to the same event twice!");
					return;
				}
			}
			event_type->second.push_back(listener);
		}
	}
}